﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

/// <summary>
/// 加载本地或在线的资源
/// </summary>
public class ResSlightly : MonoSingleton<ResSlightly> {

    const string _res_save_path = "Res_slightly";

    public enum ResPathType
    {
        Local,
        Network,
    }

    public Dictionary<string, UnityEngine.Object> _cache_path_Object;

    protected override void Init()
    {
        base.Init();
        _cache_path_Object = new Dictionary<string, UnityEngine.Object>();

        string local_save_path = FileTools.CombinePath(Application.persistentDataPath, _res_save_path);
        if (!FileTools.IsDirectoryExist(local_save_path))
            FileTools.CreateDirectory(local_save_path);
    }




    #region 暴露的接口

    /// <summary>
    /// 加载一张图片
    /// </summary>
    /// <param name="path">网络路径或本地路径</param>
    /// <param name="pathtype"></param>
    /// <param name="callback"></param>
    /// <param name="isAutoSave">图片是否要自动保存</param>
    /// <param name="iscache"></param>
    public void LoadTexture2D(string path,Action<Texture2D> callback, bool isAutoSave = true,bool iscache = false)
    {
        ResPathType pathtype = path.Contains("http://") ? ResPathType.Network : ResPathType.Local;
        // Res_slightly/aa.jpg
        string local_save_path = GetLocalSavePathFromFullPath(path);
        if (isAutoSave)
        {
            if (IsFileExist(local_save_path))
            {
                LoadTexture2D(local_save_path, ResPathType.Local, callback, iscache);
            }
            else
            {
                LoadTexture2D(path, pathtype, (tex) => {
                    callback(tex);
                    //存储图片
                    byte[] textureStream = tex.EncodeToPNG();
                    string save_path = FileTools.CombinePath(Application.persistentDataPath, local_save_path);
                    System.IO.File.WriteAllBytes(save_path, textureStream);
                }, iscache);
            }
        }
        else
        {
            LoadTexture2D(path, pathtype, callback, iscache);
        }
    }


    public void LoadAssetBundle(string path, Action<AssetBundle> callback, bool iscache = false)
    {
        ResPathType pathtype = path.Contains("http://") ? ResPathType.Network : ResPathType.Local;
        path = GetFullPath(path, pathtype);
        if (_cache_path_Object.ContainsKey(path))
        {
            callback(_cache_path_Object[path] as AssetBundle);
        }
        else
        {
            StartCoroutine(StartLoad(path, (www) =>
            {
                callback(www.assetBundle);
                CacheObject(path, iscache, www.assetBundle);
            }));
        }
    }

    public void LoadTextAsset(string path, Action<string> callback, bool iscache = false)
    {
        ResPathType pathtype = path.Contains("http://") ? ResPathType.Network : ResPathType.Local;
        GetFullPath(path, pathtype);
        StartCoroutine(StartLoad(path, (www) => {
            callback(www.text);
        }));
    }

    public void LoadMovieTexture(string path, Action<MovieTexture> callback, bool iscache = false)
    {
        ResPathType pathtype = path.Contains("http://") ? ResPathType.Network : ResPathType.Local;
        path = GetFullPath(path, pathtype);
        //Debug.LogError(path);
        if (_cache_path_Object.ContainsKey(path))
        {
            callback(_cache_path_Object[path] as MovieTexture);
        }
        else
        {
            StartCoroutine(StartLoad(path, (www) => {
                callback(www.GetMovieTexture());
                CacheObject(path, iscache, www.GetMovieTexture());
            }));
        }
    }

    public void LoadAudio(string path, Action<AudioClip> callback, bool iscache = false)
    {
        ResPathType pathtype = path.Contains("http://") ? ResPathType.Network : ResPathType.Local;
        path = GetFullPath(path, pathtype);
        //Debug.LogError(path);
        if (_cache_path_Object.ContainsKey(path))
        {
            callback(_cache_path_Object[path] as AudioClip);
        }
        else
        {
            StartCoroutine(StartLoad(path, (www) => {
                callback(www.GetAudioClip());
                CacheObject(path, iscache, www.GetAudioClip());
            }));
        }
    }

    public void LoadBytesDownload(string path, Action<byte[]> callback, bool iscache = false)
    {
        ResPathType pathtype = path.Contains("http://") ? ResPathType.Network : ResPathType.Local;
        GetFullPath(path, pathtype);
        StartCoroutine(StartLoad(path, (www) => {
            callback(www.bytes);
        }));
    }


    #endregion

    private void LoadTexture2D(string path, ResPathType pathtype, Action<Texture2D> callback, bool iscache = false)
    {
        path = GetFullPath(path, pathtype);
        //Debug.LogError(path);
        if (_cache_path_Object.ContainsKey(path))
        {
            callback(_cache_path_Object[path] as Texture2D);
        }
        else
        {
            StartCoroutine(StartLoad(path, (www) => {
                callback(www.texture);
                CacheObject(path, iscache, www.texture);
            }));
        }
    }

    


    private static string GetFullPath(string path, ResPathType pathtype)
    {
        return pathtype == ResPathType.Local ? "file:///" + FileTools.CombinePath(Application.persistentDataPath,path) : path;
    }

    private void CacheObject(string path, bool iscache, UnityEngine.Object obj)
    {
        if (iscache)
        {
            if (!_cache_path_Object.ContainsKey(path))
                _cache_path_Object.Add(path, obj);
        }
    }


    private IEnumerator StartLoad(string url,Action<WWW> callback)
    {
        WWW www = new WWW(url);
        yield return www;
        if (string.IsNullOrEmpty(www.error))
        {
            if (callback != null) callback(www);
        }
        else
        {
            Debug.LogError(www.error);
        }
    }


    public void DestroyAllResouce()
    {
        if (_cache_path_Object != null || _cache_path_Object.Count > 0)
        {
            foreach (var item in _cache_path_Object.Values)
                Destroy(item);
            _cache_path_Object.Clear();
        }
    }

    public void DestroyResource(string key)
    {
        if (_cache_path_Object.ContainsKey(key))
        {
            Destroy(_cache_path_Object[key]);
            _cache_path_Object.Remove(key);
        }
    }

    public bool IsFileExist(string path)
    {
        string save_path = FileTools.CombinePath(Application.persistentDataPath, GetLocalSavePathFromFullPath(path));
        //Debug.Log("save_path: " + save_path);

        return FileTools.IsFileExist(save_path);
    }

    private static string GetLocalSavePathFromFullPath(string path)
    {
        string filename = FileTools.GetFullName(path);
        string save_path = FileTools.CombinePaths(_res_save_path, filename);
        return save_path;
    }

    protected override void OnDestroy()
    {
        base.OnDestroy();
    }

}
